package starComponent.elements;

import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;

import starComponent.E_PossibleBranches;

import data.visu.structures.ValueAndString;
import data.visu.utils.Numbers;

/**
 * @author Charles Perin
 * 11 avr. 2011
 * LIMSI - INRIA Rennes
 * charles.perin@free.fr
 */
public class Ladder {
	
	private E_PossibleBranches branchType;

	private double min, max, step;

	private Color tickColor, labelColor;

	private boolean paintTicks, paintLabels;

	private HashMap<Double, LadderTick> ladderMap;

	public static final int LINEAR=0, LOGARITHMIC=1;

	private int mode = LINEAR;


	/**
	 * Constructeur d'une echelle lineaire
	 * @param min la valeur min de l'echelle
	 * @param max la valeur max de l'echelle
	 * @param step le pas de l'echelle, pris en compte uniquement si echelle lineaire
	 * @param paintTicks vrai si dessin des ticks
	 * @param paintLabels vrai si dessin des valeurs
	 * @param tickColor la couleur des ticks
	 * @param labelColor la couleur des labels
	 */
	public Ladder(E_PossibleBranches branchType, boolean paintTicks, boolean paintLabels, Color tickColor, Color labelColor){
		this.tickColor = tickColor;
		this.labelColor = labelColor;
		this.ladderMap = new HashMap<Double, LadderTick>();
		this.step=branchType.getStep();
		this.mode = LINEAR;
		this.min=branchType.getMinValue();
		this.max=branchType.getMaxValue();
		this.paintLabels = paintLabels;
		this.paintTicks=paintTicks;
		this.branchType = branchType;
	}

	/**
	 * Constructeur d'une echelle logarithmique: valeur min forcee a 1, calcul auto du pas. Max doit etre un multiple de 10.
	 * @param max la valeur max de l'echelle
	 * @param paintTicks vrai si dessin des ticks
	 * @param paintLabels vrai si dessin des valeurs
	 * @param tickColor la couleur des ticks
	 * @param labelColor la couleur des labels
	 */
	public Ladder(double max, boolean paintTicks, boolean paintLabels, Color tickColor, Color labelColor){
		if(max%10!=0) System.err.println("Ladder logarithmique: max doit etre un multiple de 10 !");
		this.tickColor = tickColor;
		this.labelColor = labelColor;
		this.ladderMap = new HashMap<Double, LadderTick>();
		this.mode = LOGARITHMIC;
		this.min=0;
		this.max=max;
		this.paintLabels = paintLabels;
		this.paintTicks=paintTicks;
	}


	public void updateLadderMap(A_StarBranch branch) {
		ladderMap.clear();
		switch(mode){
		case LINEAR:
			switch(branchType.getType()){
			case E_PossibleBranches.QUANTITATIVE_SLIDER:
			case E_PossibleBranches.QUANTITATIVE_BISLIDER:
				for(double val=min; val<=max;val+=step){
					ladderMap.put(val, new LadderTick(branch, val, Double.toString(Numbers.roundDouble(val, 2))));
				}
				break;
				
			case E_PossibleBranches.QUALITATIVE_SLIDER:
			case E_PossibleBranches.QUALITATIVE_BISLIDER:
				for(ValueAndString vs:branchType.getLabels()){
					ladderMap.put((double) vs.getValue(), new LadderTick(branch, vs.getValue(), vs.getString()));
				}
				break;
			}

			break;
		case LOGARITHMIC:
			int nbTicks=0;
			double tmp = max;
			while(tmp>=1){
				tmp=tmp/10;
				nbTicks++;
			}
			double stepInPixels = branch.getLength()/nbTicks;
			step = max/(nbTicks-1);

			ladderMap.put(0.0, new LadderTick(branch, 0.0, Double.toString(Numbers.roundDouble(0.0, 2))));
			double i=1;
			for(double val=1;val<=max;val=val*10){
				//miltiples de 10
				ladderMap.put(val, new LadderTick(branch, val, Double.toString(Numbers.roundDouble(val, 2))));

				if(val>=10){
					//valeurs intermediaires
					ladderMap.put(val*0.25, new LadderTick(branch, val*0.25, Double.toString(Numbers.roundDouble(val*0.25, 2))));
					ladderMap.put(val*0.5, new LadderTick(branch, val*0.5, Double.toString(Numbers.roundDouble(val*0.5, 2))));
					ladderMap.put(val*0.75, new LadderTick(branch, val*0.75, Double.toString(Numbers.roundDouble(val*0.75, 2))));
				}
				i = i*stepInPixels;
			}

			ArrayList<Double> tickValues = new ArrayList<Double>();
			tickValues.add(0.0);
			for(double val=1;val<=max;val*=10){
				tickValues.add(val);
			}
			break;
		default:
			System.err.println("Ladder: mode non connu");
		}

	}

	public double getMin() {
		return min;
	}

	public void setMin(double min) {
		this.min = min;
	}

	public double getMax() {
		return max;
	}

	public void setMax(double max) {
		this.max = max;
	}

	public double getStep() {
		return step;
	}

	public void setStep(double step) {
		this.step = step;
	}

	public boolean isPaintTicks() {
		return paintTicks;
	}

	public void setPaintTicks(boolean paintTicks) {
		this.paintTicks = paintTicks;
	}

	public boolean isPaintLabels() {
		return paintLabels;
	}

	public void setPaintLabels(boolean paintLabels) {
		this.paintLabels = paintLabels;
	}


	public void setTickColor(Color tickColor) {
		this.tickColor = tickColor;
	}


	public Color getTickColor() {
		return tickColor;
	}


	public void setLabelColor(Color labelColor) {
		this.labelColor = labelColor;
	}


	public Color getLabelColor() {
		return labelColor;
	}


	public HashMap<Double, LadderTick> getLadderMap() {
		return ladderMap;
	}


	public int getMode() {
		return mode;
	}

	public void setMode(int mode) {
		this.mode = mode;
	}


}
